<?php
/**
 * Created by PhpStorm.
 *
 * @Date: 2017-08-01
 * @Time: 12:05
 * @Author: cdkay
 * @Email: network@iyuanma.net
 *
 * @File： User.php
 */
namespace app\api\controller;

use app\api\model\curriculum\Curriculum;
use app\api\model\DrawPercentageRecord;
use app\api\model\special\UserSubscribeSpecial;
use app\api\model\user\Users;
use app\common\controller\Base;
use app\common\lib\rongcloud\RongCloud;
use app\common\model\AgencySalesman;
use app\common\model\ApiResponse;
use app\common\model\BuyBill;
use app\common\model\UserCreditRecord;
use app\common\model\UserNoticeMessage;
use app\common\model\zds\Customer;
use app\common\model\zds\Salesman;
use library\IntConvert;
use library\ServerAPI;
use think\Cache;
use think\Db;
use think\Exception;
use think\Log;
use think\Request;
use think\Validate;

class User extends Base
{
    protected $users;
    protected $sms;
    protected $subscribe;

    public function __construct()
    {
        parent::__construct();

        $this->sms = ServerAPI::getInstance();

        $this->users = new \app\api\model\user\Users();
        $this->subscribe = new UserSubscribeSpecial();
    }

    /**
     * 用户注册接口
     * @update 2018-04-12 wangxuejiao
     *     修改注册逻辑
     * @return ApiResponse
     */
    public function register()
    {
        $form = $this->getAndCheckForm([
            ['mobile', 'require|^1[3-9]\d{9}$', '手机号码不能为空|手机号码格式不正确'], // 手机号码
            ['code', 'require|^\d{4}$', '短信验证码不能为空|短信验证码格式不正确'], // 短信验证码
            ['password', 'require|length:6,255', '密码不能为空|密码长度不能小于6位'], // 密码
        ]);

        if ($this->users->query_user_exist($form['mobile'])) {
            return ApiResponse::error(ApiResponse::ERR_EXISTS, '您的手机号已经注册，可以直接登录！');
        }

        $verifyCode = $this->sms->verifyCode($form['mobile'], $form['code']);
        if ($verifyCode['code'] != 200) {
            return ApiResponse::error(ApiResponse::ERR_OPERATE_FAILED, '短信验证码验证失败');
        }

        $userData = [
            'mobile' => $form['mobile'],
            'password' => passEncrypt($form['password']),
            'regtime' => time(),
        ];
        if (!empty($form['realname'])) {
            $userData['realname'] = $form['realname'];
        }
        if (!empty($form['invite_code'])) {
            $promoter = Users::findByExtensionCode($form['invite_code']);
            if (empty($promoter)) {
                return ApiResponse::error(ApiResponse::ERR_OPERATE_FAILED, '邀请码无效');
            } else {
                $userData['promoter_id'] = $promoter->id;
            }
        }
        $user = Users::create($userData);
        Users::updateForExtensionCode($user->id, IntConvert::toString($user->id));

        Users::set_user_ability($user->id);
        // 注册送积分
        Users::creditTask($user->id, UserCreditRecord::CHANGE_TYPE_REGISTER);
        // 注册送课程
        BuyBill::addBillGift($user->id);

        $now = time();
        $token = userToken($user->id, $now);
        saveUserToken($user->id, $token);

        $user = Users::get($user->id);

        // 检查用户的聊天服务器token
        $chat = Users::chatToken($user->toArray());

        $data = [
            'uid' => $user->id, // 用户id
            'token' => $token, // 用户令牌
            'mobile' => $user->mobile, // 手机号
            'nickname' => ($user->nickname?:mobile_hidden(substr($user->mobile, 0, 11)))?:$user->id, // 昵称
            'avatar' => $user->avatar ?? Users::defaultAvatar(), // 用户头像
            'credit' => $user->credit ?? 0, // 用户积分
            'invite_credit' => $user->invite_credit ?? 0, // 推广积分
            'regtime' => $user->regtime ?? $now, // 注册时间
            'gender' => $user->gender ?? 1, // 性别
            'chat' => $chat, // 聊天服务器id和token
            'is_vip' => Customer::is_vip($user->id), // 是否为vip用户
        ];
        // 获取当前用户邀请人的邀请码
        if (!empty($user['promoter_id']) && $user['promoter_id']) {
            $parentUser = Users::get(['id'=>$user['promoter_id']]);
            $data['agency_invite_code'] = $parentUser['extension_code'];
        } else {
            $data['agency_invite_code'] = '';
        }

        return ApiResponse::success($data);
    }

    /**
     * quickLogon
     * 用户快速登录
     * 有账号自动登录，无账号自动创建并登录
     * @api http://xxx/api/user/fast_login
     *      mobile 必填 手机号码
     *      code 必填 短信验证码
     *      realname 选填 用户真实姓名
     *      invite_code 选填 推广员邀请码
     *
     * @author zhengkai
     * @date 2017-08-01
     * @update zhengkai 2017-10-30 增加用户实名认证状态字段
     *         zhengkai 2018-01-23 增加用户真实姓名字段
     *
     * @param Request $request 传入的form数据
     * @return \think\response\Json
     */
    public function fast_login(Request $request)
    {
        $form = $request->post();

        // 表单验证
        $validate = new Validate([
            ['mobile', 'require|^1[3-9]\d{9}$', '手机号码不能为空|手机号码格式不正确'], // 手机号码
            ['code', 'require|^\d{4}$', '短信验证码不能为空|短信验证码格式不正确'], // 短信验证码
        ]);
        if (!$validate->check($form)) return json(array('code' => 1010, 'msg' => $validate->getError(), 'data' => null));

        // 验证短信验证码
        $verifyCode = $this->sms->verifyCode($form['mobile'], $form['code']);
        if ($verifyCode['code'] != 200) return json(array('code' => 1012, 'msg' => '短信验证码验证失败', 'data' => null));

        $user_data = $this->users->get_user_single(['mobile' => $form['mobile']]);
            // 判断用户是否填写推广员邀请码
        $promoter_id=null;
        if (!empty($form['invite_code'])) {
            if($user_data && $user_data->promoter_id) return json(array('code' => ApiResponse::ERR_invited, 'msg' => '您已经被邀请过了','data' => null));
            // 查询邀请码是否有效
            $promoter=Users::findByExtensionCode($form['invite_code']);
            if (empty($promoter)) return json(array('code' => 1013, 'msg' => '邀请码无效！', 'data' => null));
            $promoter_id=$promoter->id;
        }

        // 判断用户是否存在
        $isRealName=0;
        $realNameData=[];
        if(!$user_data){
            $uid = $this->users->create_user($form['mobile'], $form['realname'] ?? '');
            if(!$uid) return json(array('code' => 1012, 'msg' => '登录失败', 'data' => null));
            if($promoter_id == $uid)  return json(array('code' => 1013, 'msg' => '这是您自己的邀请码！'));
            Users::updateArray($uid, ['extension_code'=>IntConvert::toString($uid),'promoter_id'=>$promoter_id]);
            // 获取当前新用户数据
            $user_data = $this->users->get_user_single(['id' => $uid]);
            // 注册送积分
            Users::creditTask($uid, UserCreditRecord::CHANGE_TYPE_REGISTER);
            // 注册送课程
            BuyBill::addBillGift($uid);
            // 生成用户技能等级数据
            Users::set_user_ability($user_data['id']);
        }else{
            if($promoter_id){
                if ($promoter_id == $user_data['id']) return json(array('code' => 1013, 'msg' => '这是您自己的邀请码！'));
                Users::updateArray($user_data['id'], ['promoter_id'=>$promoter_id]);
            }
            // 查询用户是否已通过实名认证
            $realNameData = Db::query("select realname as user_relname,identity_card_number as user_cardno from real_name_authentication where user_id={$user_data['id']} and auth_status='true'");
            $isRealName = !empty($realNameData) ? 1 : 0;
        }

        if ($promoter_id) {
            // 保存邀请数据到数据库
            $credit = Users::creditTask($promoter->id, UserCreditRecord::CHANGE_TYPE_INVITE_USER);
            UserNoticeMessage::sendInviteRegisterMessage($promoter->id, $form['mobile'], $credit,'掌乾财经：您邀请的“%s”已完成绑定，恭喜您获得%s积分。','邀请注册');
        }

        // 生成 user token
        $createUserToken = userToken($user_data['id'], time());
        // 保存 user token
        $saveUserToken = saveUserToken($user_data['id'], $createUserToken);

        // 检查用户的聊天服务器token
        $chat = Users::chatToken($user_data);

        // 获取当前用户邀请人的邀请码
        $data = [
            'uid' => $user_data['id'], // 用户id
            'token' => $createUserToken, // 用户密钥 user token
            'mobile' => $user_data['mobile'], // 手机号
            'nickname' => ($user_data['nickname']?:mobile_hidden(substr($user_data['mobile'], 0, 11)))?:$user_data['id'], // 昵称
            'avatar' => $user_data['avatar']?:Users::defaultAvatar(), // 用户头像
            'credit' => $user_data['credit'], // 用户积分
            'invite_credit' => $user_data['invite_credit'], // 推广积分
            'regtime' => $user_data['regtime'], // 注册时间
            'gender' => $user_data['gender'], // 性别
            'chat' => $chat, // 聊天服务器id和token
            'is_realname' => $isRealName, // 是否实名认证 1=是 0=否
            'user_realname' => $isRealName ? $realNameData[0]['user_relname'] : '', // 用户真实姓名
            'user_cardno' => $isRealName ? substr($realNameData[0]['user_cardno'], 0, 3) . '*****' . substr($realNameData[0]['user_cardno'], strlen($realNameData[0]['user_cardno']) - 2, strlen($realNameData[0]['user_cardno'])) : '', // 用户身份证码
            'is_vip' => Customer::is_vip($user_data['id']), // 是否为vip用户
        ];
        // 获取当前用户邀请人的邀请码
        if (!empty($user_data['promoter_id']) && $user_data['promoter_id']) {
            $parentUser = Users::get(['id'=>$user_data['promoter_id']]);
            $data['agency_invite_code'] = $parentUser['extension_code'];
        } else {
            $data['agency_invite_code'] = '';
        }

        return json(array('code' => 200, 'msg' => '登录成功', 'data' => $data));
    }

    /**
     * login
     * 普通登录，需要账号密码
     * @api http://xxx/api/user/login
     *      mobile 必填 手机号码
     *      password 必填 登陆密码
     *
     * @author zhengkai
     * @date 2017-08-02
     * @update zhengkai 2017-10-30 增加用户实名认证状态字段
     *
     * @param Request $request 传入的form参数
     * @return \think\response\Json
     */
    public function login(Request $request)
    {
        $form = $request->post();

        // 表单验证
        $validate = new Validate([
            ['mobile', 'require', '登录密码不能为空'], // 手机号或用户id
            ['password', 'require', '登录密码不能为空'], // 登录密码
        ]);
        if (!$validate->check($form)) return json(array('code' => 1010, 'msg' => $validate->getError(), 'data' => null));
        $user_data=strlen($form['mobile'])>8 ? $this->users->where('mobile',$form['mobile'])->find() : $this->users->where('id',$form['mobile'])->find();
        // 验证用户名是否有效
        if (empty($user_data)) return json(array('code' => 1012, 'msg' => '账号或密码不正确', 'data' => null));

        $pass = passEncrypt($form['password']);
        if ($pass !== $user_data['password']) return json(array('code' => 1012, 'msg' => '账号或密码不正确', 'data' => null));

        // 生成 user token
        $createUserToken = userToken($user_data['id'], time());
        // 保存 user token
        saveUserToken($user_data['id'], $createUserToken);

        // 检查用户的聊天服务器token
        $chat = Users::chatToken($user_data);

        // 查询用户是否已通过实名认证
        $realNameData = Db::query("select realname as user_relname,identity_card_number as user_cardno from real_name_authentication where user_id={$user_data['id']} and auth_status='true'");
        $isRealName = !empty($realNameData) ? 1 : 0;

        // 获取当前用户邀请人的邀请码
        $parentUser = Users::get(['id'=>$user_data['promoter_id']]);
        $data = array(
            'uid' => $user_data['id'], // 用户id
            'token' => $createUserToken, // 用户密钥 user token
            'mobile' => $user_data['mobile'], // 手机号
            'nickname' => ($user_data['nickname']?:mobile_hidden(substr($user_data['mobile'], 0, 11)))?:$user_data['id'], // 昵称
            'avatar' => $user_data['avatar']?:Users::defaultAvatar(), // 用户头像
            'credit' => $user_data['credit'], // 用户积分
            'invite_credit' => $user_data['invite_credit'], // 推广积分
            'regtime' => $user_data['regtime'], // 注册时间
            'gender' => $user_data['gender'], // 性别
            'chat' => $chat, // 聊天服务器id和token
            'is_realname' => $isRealName, // 是否实名认证 1=是 0=否
            'user_realname' => $isRealName ? $realNameData[0]['user_relname'] : '', // 用户真实姓名
            'user_cardno' => $isRealName ? substr($realNameData[0]['user_cardno'], 0, 3) . '*****' . substr($realNameData[0]['user_cardno'], strlen($realNameData[0]['user_cardno']) - 2, strlen($realNameData[0]['user_cardno'])) : '', // 用户身份证码
            'is_vip' => Customer::is_vip($user_data['id']), // 是否为vip用户
        );
        if (!empty($user_data['promoter_id']) && $user_data['promoter_id']) {
            $parentUser = Users::get(['id'=>$user_data['promoter_id']]);
            $data['agency_invite_code'] = $parentUser['extension_code'];
        } else {
            $data['agency_invite_code'] = '';
        }

        return json(array('code' => 200, 'msg' => '登录成功', 'data' => $data));
    }

    /**
     * 用于ios游客模式登录
     *
     * @return ApiResponse
     */
    public function ios_login()
    {
        $this->iOSVerify();

        $form = $this->getAndCheckForm([
            ['apple_id', 'require',],
        ]);

        $apple_id = $form['apple_id'];
        $user = Users::get(['mobile' => $apple_id]);
        if (is_null($user)) {
            $user = Users::create(['mobile' => $apple_id, 'regtime' => time(), 'register_from' => Users::REGISTER_FROM_IOS_TOURIST]);
            $user = Users::get($user->id);
            Users::creditTask($user->id, UserCreditRecord::CHANGE_TYPE_REGISTER);
            Users::set_user_ability($user->id);
        }

        $chat = Users::chatToken($user->toArray());
        // 生成 user token
        $token = userToken($user->id, time());
        // 保存 user token
        saveUserToken($user->id, $token);

        $data = array(
            'uid' => $user['id'], // 用户id
            'token' => $token, // 用户密钥 user token
            'mobile' => $user['mobile'], // 手机号
            'nickname' => ($user['nickname']?:mobile_hidden(substr($user['mobile'], 0, 11)))?:$user['id'], // 昵称
            'avatar' => $user['avatar']?:Users::defaultAvatar(), // 用户头像
            'credit' => $user['credit'], // 用户积分
            'invite_credit' => $user['invite_credit'], // 推广积分
            'regtime' => $user['regtime'], // 注册时间
            'gender' => $user['gender'], // 性别
            'agency_invite_code' => '', // 被邀请人邀请码
            'chat' => $chat, // 聊天服务器id和token
            'is_realname' => 0, // 是否实名认证 1=是 0=否
            'user_realname' => $user['realname'], // 用户真实姓名
            'user_cardno' => '', // 用户身份证码
            'is_vip' => Customer::is_vip($user['id']), // 是否为vip用户
        );

        return ApiResponse::success($data);
    }

    /**
     * 每日签到接口
     *
     * @return ApiResponse
     */
    public function daily_attend()
    {
        $uid = checkUserToken(true);
        $re = Users::creditTask($uid, UserCreditRecord::CHANGE_TYPE_ATTENDANCE);
        if ($re) return ApiResponse::success();
        else return ApiResponse::error(ApiResponse::ERR_OPERATE_FAILED, '您今天已经签到');
    }

    // 退出登录
    public function logout()
    {
        // 登录检测
        checkUserToken(true);

        $header = Request::instance()->header();

        // 表单验证
        $validate = new Validate([
            ['uid', 'require|^\\d+$', '用户id不能为空|参数类型不正确']
        ]);
        if (!$validate->check($header)) return json(array('code' => 1010, 'msg' => $validate->getError(), 'data' => null));

        $result = Cache::tag('user_token')->rm('user_' . $header['uid']);

        if ($result) {
            return json(array('code' => 200, 'msg' => '退出成功', 'data' => null));
        } else {
            return json(array('code' => 1012, 'msg' => '操作失败', 'data' => null));
        }
    }

    /**
     * pass_reset
     * 用户登录密码重置
     * @api http://xxx/api/user/pass_reset
     *      mobile 验证账号时必填 手机号码
     *
     *      code 重置密码时必填 短信验证码
     *      password 重置密码时必填 新的登录密码
     *
     *      setup 必填 操作步骤
     *
     * @author zhengkai
     * @date 2017-08-08
     *
     * @return \think\response\Json
     */
    public function pass_reset()
    {
        $form = input('post.');

        // 表单验证
        $validate1 = new Validate([
            ['mobile', 'require|^1[3-9]\d{9}$', '手机号码不能为空|手机号码格式不正确'], // 手机号码
        ]);
        if (!$validate1->check($form)) return json(array('code' => 1010, 'msg' => $validate1->getError(), 'data' => null));

        /***** 第一步 验证手机账号 *****/
        switch ($form['setup']) {
            case 1: // 第一步 验证手机账号
                $is_exist = $this->users->query_user_exist($form['mobile']);
                if (!$is_exist) return json(array('code' => 1012, 'msg' => '用户不存在', 'data' => null));

                return json(array('code' => 200, 'msg' => 'success', 'data' => null));
                break;
            case 2: // 第二步 重置密码
                $is_exist = $this->users->query_user_exist($form['mobile']);
                if ($is_exist) {
                    // 表单验证
                    $validate2 = new Validate([
                        ['code', 'require|^\d{4}$', '短信验证码不能为空|短信验证码格式不正确'], // 短信验证码
                        ['password', 'require|length:6,20', '登录密码不能为空|密码长度必须为6~20位'], // 登录密码
                    ]);
                    if (!$validate2->check($form)) return json(array('code' => 1010, 'msg' => $validate2->getError(), 'data' => null));

                    // 验证短信验证码
                    $verifyCode = $this->sms->verifyCode($form['mobile'], $form['code']);
                    if ($verifyCode['code'] != 200) return json(array('code' => 1012, 'msg' => '短信验证码验证失败', 'data' => null));

                    // 更新登录密码
                    $result = $this->users->where('mobile', $form['mobile'])->update(['password' => passEncrypt($form['password'])]);
                    if ($result) {
                        return json(array('code' => 200, 'msg' => '操作成功', 'data' => null));
                    } else {
                        return json(array('code' => 1012, 'msg' => '操作失败', 'data' => null));
                    }
                } else {
                    return json(array('code' => 1012, 'msg' => '用户不存在', 'data' => null));
                }
                break;
        }
    }

    /**
     * 修改密码，需要输入旧密码
     *
     * @return ApiResponse
     */
    public function update_password()
    {

        $uid = checkUserToken(true);

        $me = Users::get($uid);

        $form = $this->getAndCheckForm([
            ['old_password', 'require', '旧密码不能为空',],
            ['new_password', 'require', '新密码不能为空',],
        ]);

        if (passEncrypt($form['old_password']) == $me->password) {
            $me->password = passEncrypt($form['new_password']);
            $me->save();
            return ApiResponse::success();
        } else {
            return ApiResponse::error(ApiResponse::ERR_INVALID_PASSWORD, '旧密码错误');
        }

    }

    /**
     * 获取用户信息
     *
     * @return ApiResponse
     */
    public function user_info()
    {

        // 强制检查登录
        $uid = checkUserToken(true);

        // 获取用户个人信息
        $data = Users::info($uid);

        return ApiResponse::success($data);
    }

    /**
     * 修改个人资料，头像、昵称、性别
     *
     * @return ApiResponse
     */
    public function update_user_info()
    {

        $uid = checkUserToken(true);
        $user = Users::get($uid);
        if (empty($user)) return ApiResponse::error(ApiResponse::ERR_TOKEN_INVALID, '用户未登录');

        $form = $this->getAndCheckForm([]);

        Db::startTrans();
        try {
            $fill = 0;
            foreach (['avatar', 'nickname', 'gender',] as $k) {
                if (!empty($form[$k])) {
                    $fill++;
                    $user->$k = $form[$k];
                }
            }
            $user->save();
            if ($fill > 0) Users::creditTask($user->id, UserCreditRecord::CHANGE_TYPE_IMPROVE_MATERIAL);

            $data = [
                'uid' => $user->id, // 用户id
                'mobile' => $user->mobile, // 手机号
                'nickname' => ($user->nickname?:mobile_hidden(substr($user->mobile, 0, 11)))?:$user->id, // 昵称
                'avatar' => $user->avatar?:Users::defaultAvatar(), // 用户头像
                'credit' => $user->credit, // 用户积分
                'regtime' => $user->regtime, // 注册时间
                'gender' => $user->gender, // 性别
                'is_vip' => Customer::is_vip($user->id), // 是否为vip用户
            ];

            if (array_key_exists('invite_code', $form) && !empty($form['invite_code'])) {
                $invite_code = Users::modify_invite_user_once($user, $form['invite_code']);
                if (!$invite_code) {
                    Db::rollback();
                    return ['code'=>1013, 'msg'=>'邀请码无效', 'data'=>null];
                    // return ApiResponse::error(ApiResponse::ERR_INVALID_INVITE_CODE, '邀请码无效');
                }
                $data['agency_invite_code'] = $invite_code;
            } else {
                $data['agency_invite_code'] = Users::get_user_invited_code($uid);
            }

            Db::commit();
            Users::updateChatInfo($user['id'], $user->toArray());

            return ApiResponse::success($data);
        } catch (\Exception $ex) {
            Db::rollback();
            Log::error($ex->getFile());
            return ApiResponse::error(ApiResponse::ERR_OPERATE_FAILED, '操作失败，请稍后再试');
        }

    }

    /**
     * app_user_curriculum
     * app我的课程数据接口
     * @api http://xxx/api/user/buy_curriculum
     *      class 选填 课程分类ID 默认获取分部分类课程数据
     *      page  选填 分页 当前第N页 默认加载第一页
     *      rows  选填 分页 每页加载N条数据 默认加载10条数据
     *
     * @author zhengkai
     * @date 2017-08-22
     *
     * @return \think\response\Json
     */
    public function user_buy_curriculum()
    {
        // 登录检测
        $uid = checkUserToken(true);

        $form = input('post.');
        if (!array_key_exists('class_id', $form) || empty($form['class_id'])) $form['class_id'] = 0;
        if (!array_key_exists('page', $form) || empty($form['page'])) $form['page'] = 1;
        if (!array_key_exists('rows', $form) || empty($form['rows'])) $form['rows'] = 10;

        $curriculumM = new Curriculum();

        return $curriculumM->get_user_buy_curriculum($form['class_id'], $uid, $form['page'], $form['rows']);
    }

    /**
     * user_ability
     * 用户技能雷达图数据接口
     *
     * @author zhengkai
     * @date 2017-0824
     *
     * @return \think\response\Json
     */
    public function user_ability()
    {
        // 登录检测
        $uid = checkUserToken(true);

        return $this->users->get_user_ability($uid);
    }

    /**
     * 获取通知消息
     *
     * @return ApiResponse
     */
    public function get_notice_message()
    {

        $uid = checkUserToken(true);

        $form = $this->getAndCheckForm([
            ['rows', 'integer',],
            ['page', 'integer',],
        ]);

        $p = self::pageFormat($form);
        $list = UserNoticeMessage::myList($uid, null, $p['limit'], $p['offset']);

        return ApiResponse::success($list);
    }

    /**
     * 设置通知消息为已读状态
     *
     * @return ApiResponse
     */
    public function set_notice_message_read()
    {

        $uid = checkUserToken(true);

        UserNoticeMessage::setRead($uid);

        return ApiResponse::success();
    }

    /**
     * user_buy_live
     * 我的直播数据接口
     * @api http://xxx/api/user/my_live
     *      page 选填 当前页数
     *      rows 选填 每页加载数据条数
     *
     * @author zhengkai
     * @date 2017-09-13
     *
     * @return \think\response\Json
     */
    public function user_buy_live()
    {
        $uid = checkUserToken(true);

        $form = input('post.');
        if (!array_key_exists('page', $form) || empty($form['page'])) $form['page'] = 1;
        if (!array_key_exists('rows', $form) || empty($form['rows'])) $form['rows'] = 10;

        $liveM = new \app\api\model\live\Live();

        return $liveM->get_buy_live($uid);
    }

    /**
     * v1.2
     * 我(推广员)的推广信息
     *
     * @todo v1.4.1废弃
     *
     * @return ApiResponse
     */
    public function my_agency_info()
    {

        $uid = checkUserToken(true);

        $info = AgencySalesman::agencyInfo($uid);
        if (empty($info['agency_code'])) {
            // 默认创建推广员，属于默认机构
            $info = AgencySalesman::createDefault($uid, true);
        }

        $today = strtotime(date('Y-m-d'));
        $timeRange = [$today - 86400, $today];

        $info['client_num'] = AgencySalesman::countInvitedUser($info['salesman_id']);
        $info['client_num_yesterday'] = AgencySalesman::countInvitedUser($info['salesman_id'], $timeRange);
        $info['total_amount'] = AgencySalesman::billTotalAmount($info['salesman_id']);
        $info['total_amount_yesterday'] = AgencySalesman::billTotalAmount($info['salesman_id'], $timeRange);
        $info['total_profit'] = strval(round($info['total_amount'] * $info['profit_rate'], 2));
        $info['total_profit_yesterday'] = strval(round($info['total_amount_yesterday'] * $info['profit_rate'], 2));

        return ApiResponse::success($info ? $info : (new \stdClass()));
    }

    /**
     * v1.0
     * 我(推广员)推广邀请的用户
     *
     * @todo v1.4.1废弃
     *
     * @deprecated
     * @return ApiResponse
     */
    public function my_invited_users()
    {

        $uid = checkUserToken(true);

        $form = $this->getAndCheckForm([
            ['rows', 'integer',],
            ['page', 'integer',],
        ]);

        $re = AgencySalesman::myInvitedUsers($uid, intval($form['rows'] ?? 10), intval($form['page'] ?? 1), $this->isPC());

        if ($this->isPC()) {
            $resp = ApiResponse::success($re['list'], $re['total']);
            $resp->month_total = $re['month_total'];
            return $resp;
        } else {
            return ApiResponse::success($re['list'], $re['total']);
        }
    }

    /**
     * v1.2
     * 我推广的客户列表
     *
     * @todo v1.4.1废弃
     *
     * @return ApiResponse
     */
    public function my_invited_clients()
    {
        $uid = checkUserToken(true);
        $form = $this->getAndCheckForm([
            ['rows', 'integer',],
            ['page', 'integer',],
            ['month', 'date',],
        ]);
        $rows = intval($form['rows'] ?? 10);
        $month = $form['month'] ?? null;
        if ($month) $timeRange = [strtotime($month), strtotime($month . ' +1 month')];
        else $timeRange = null;

        $info = AgencySalesman::agencyInfo($uid);
        if (empty($info['agency_code'])) {
            // 默认创建推广员，属于默认机构
            $info = AgencySalesman::createDefault($uid, true);
        }

        $re = AgencySalesman::listInvitedUser($info['salesman_id'], $rows, $form['page'] ?? 1, $timeRange, true);

        return ApiResponse::success($re);
    }

    /**
     * v1.2
     * 我的推广订单列表
     *
     * @todo v1.4.1废弃
     *
     * @return ApiResponse
     */
    public function my_invited_bills()
    {
        $uid = checkUserToken(true);
        $form = $this->getAndCheckForm([
            ['rows', 'integer',],
            ['page', 'integer',],
            ['month', 'date',],
        ]);
        $rows = intval($form['rows'] ?? 10);
        $month = $form['month'] ?? date('Y-m');
        $timeRange = [strtotime($month), strtotime($month . ' +1 month')];

        $info = AgencySalesman::agencyInfo($uid);
        if (empty($info['agency_code'])) {
            // 默认创建推广员，属于默认机构
            $info = AgencySalesman::createDefault($uid, true);
        }

        $list = AgencySalesman::bills($info['salesman_id'], $rows, $form['page'] ?? 1, $timeRange);
        foreach ($list as & $item) {
            $item['profit'] = strval(round($item['pay_amount'] * $info['profit_rate'], 2));
        }
        $totalAmount = AgencySalesman::billTotalAmount($info['salesman_id'], $timeRange);
        $totalProfit = strval(round($totalAmount * $info['profit_rate'], 2));

        return ApiResponse::success([
            'list' => $list,
            'total_amount' => $totalAmount,
            'total_profit' => $totalProfit,
        ]);
    }

    /**
     * user_real_name
     * 用户实名认证接口
     * @api http://xxx/api/user/realname
     *
     * @author zhengkai
     * @date 2017-10-30
     *
     * @return \think\response\Json
     */
    public function user_real_name()
    {
        $uid = checkUserToken(true);

        $form = input('post.');

        // 表单验证
        $validate = new Validate([
            ['card_no', 'require|checkCardNo', '身份证号码不能为空|身份证格式不正确'],
            ['real_name', 'require', '真实姓名不能为空'],
        ]);
        // 自定义验证规则：身份证验证
        $validate->extend('checkCardNo', function ($value) {
            return 1 === preg_match('/^(\d{15}$|^\d{18}$|^\d{17}(\d|X|x))$/', (string)$value);
        });
        if (!$validate->check($form)) return json(array('code' => 1010, 'msg' => $validate->getError(), 'data' => null));

        return $this->users->real_name_auth($uid, $form['card_no'], $form['real_name']);
    }

    /**
     * 积分中心
     *
     * @return ApiResponse
     */
    public function credit_home()
    {
        $uid = checkUserToken(true);
        $data = Users::infoNew($uid);
        $data['tasks'] = UserCreditRecord::getUserTasks($uid,
            UserCreditRecord::CHANGE_TYPE_ATTENDANCE,
            UserCreditRecord::CHANGE_TYPE_FOLLOWED_TEACHER);
        $re = Curriculum::queryCreditEnable(1, 3, false, $uid);
        $data['curriculum'] = $re['list'] ?? [];

        return ApiResponse::success($data);
    }

    /**
     * 获取我的积分统计
     *
     * @return ApiResponse
     */
    public function credit()
    {
        $uid = checkUserToken(true);
        $user = Users::get($uid);
        $credits = UserCreditRecord::userStatistics($uid);
        $credits['total'] = $user->credit;
        $credits['uid'] = $user->id;

        return ApiResponse::success($credits);
    }

    /**
     * 获取我的积分任务
     *
     * @return ApiResponse
     */
    public function credit_task()
    {

        $uid = checkUserToken(true);

        $tasks = UserCreditRecord::getUserTasks($uid);

        return ApiResponse::success($tasks);
    }

    /**
     *
     * @return ApiResponse
     */
    public function credit_record()
    {

        $uid = checkUserToken(true);

        $form = $this->getAndCheckForm([
            ['rows', 'integer',],
            ['page', 'integer',],
        ]);

        $re = UserCreditRecord::listUserRecord($uid, $form['rows'] ?? 10, $form['page'] ?? 1, $this->isPC());

        return ApiResponse::success($re['list'], $re['total'] ?? null, null, $re['lastPage'] ?? null);
    }

    /**
     * user_special
     * 我的专栏数据接口
     * @api http://xxx/api/user/special
     *      POST
     *          page  选填 当前页数，默认1
     *          limit 选填 每页加载数据条数，默认10
     *
     * @author zhengkai
     * @date 2018-01-17
     * @version 1.3
     *
     * @return \think\response\Json
     */
    public function user_special()
    {
        $uid = checkUserToken(true);

        $form = input('post.');

        // 表单验证
        $validate = new Validate([
            ['page', '^\\d+$', 'page参数类型不正确'],
            ['limit', '^\\d+$', 'limit参数类型不正确']
        ]);
        if (!$validate->check($form)) return json(array('code' => 1010, 'msg' => $validate->getError(), 'data' => null));

        if (!isset($form['page'])) $form['page'] = 1;
        if (!isset($form['limit'])) $form['limit'] = 10;

        $result = $this->subscribe->getUserSubscribe($uid, $form['page'], $form['limit']);

        return json(array('code' => 200, 'msg' => 'success', 'data' => $result));
    }

    /**
     * my_ask
     * 我的问答
     * @api POST http://xxx/api/user/my_ask
     *      status  必填  问答状态：0=未回答，1=已回答，3=已过期
     *      page    选填  当前页数，默认1
     *      limit   选填  每页加载数，默认10
     *
     * @author zhengkai
     * @date 2018-03-08
     * @version 1.4
     *
     * @return \think\response\Json
     */
    public function my_ask()
    {
        $uid = checkUserToken(true);
        $form = $this->getAndCheckForm([
            ['status', 'require|integer', '问答状态不能为空'],
            ['page', 'integer',],
            ['limit', 'integer',],
        ]);
        if (!isset($form['page'])) $form['page'] = 1;
        if (!isset($form['limit'])) $form['limit'] = 10;

        $result = \app\api\model\ask\Ask::getUserAsk($uid, $form['status'], $form['page'], $form['limit']);

        return json(array('code' => 200, 'msg' => 'success', 'data' => $result));
    }

    /**
     * new_user_init
     * 新注册用户初始化数据 赠送积分、赠送课程
     * http://xxx/api/user/new_user_init
     *
     * @author zhengkai
     * @date 2018-03-28
     */
    public function new_user_init()
    {
        $form = $this->getAndCheckForm([
            ['userid', 'require|integer', '用户id不能为空|参数类型不正确'],
        ]);

        // 注册送积分
        Users::creditTask($form['userid'], UserCreditRecord::CHANGE_TYPE_REGISTER);
        // 注册送课程
        BuyBill::addBillGift($form['userid']);
    }

    /**
     * vip_invite
     * 销售系统VIP客户邀请注册(自动登录)接口
     * @api POST http://xxx/api/user/vip_invite
     *      mobile  必填  手机号码
     *      code    必填  短信验证码
     *      invite_code 必填  业务员邀请码
     *
     * @author zhengkai
     * @date 2018-04-10
     * @version 1.4.1
     *
     * @return ApiResponse
     */
    public function vip_invite()
    {
        $form = $this->getAndCheckForm([
            ['mobile', 'require|^1[3-9]\d{9}$', '手机号码不能为空|手机号码格式不正确'],
            ['code', 'require|^\d{4}$', '短信验证码不能为空|参数类型错误'],
            ['invite_code', 'require', '邀请码不能为空'],
        ]);

        // 通过邀请码获取业务员数据
        $inviteCode = $form['invite_code'];
        $salesman = Salesman::get(['invite_code' => $inviteCode]);
        if (!$salesman) ApiResponse::error(ApiResponse::ERR_INVALID_INVITE_CODE, '邀请码无效');

        // 验证短信验证码
        $verifyCode = $this->sms->verifyCode($form['mobile'], $form['code']);
        if ($verifyCode['code'] != 200) return ApiResponse::error(ApiResponse::ERR_OPERATE_FAILED, '短信验证码无效');


        // 查询掌乾用户是否存在，并获取数据
        $users = Users::get(['mobile' => $form['mobile']]);
        if ($users) {
            // 生成 user token
            $createUserToken = userToken($users->id, time());
            // 保存 user token
            saveUserToken($users->id, $createUserToken);

            $result = [
                'uid' => $users->id,                                            // 用户id
                'token' => $createUserToken,                                    // 用户密钥 user token
                'mobile' => $users->mobile,                                     // 手机号
                'nickname' => ($users->nickname?:mobile_hidden(substr($users->mobile, 0, 11)))?:$users->id,  // 昵称
                'avatar' => $users->avatar ?: Users::defaultAvatar(),             // 用户头像
                'credit' => $users->credit,                                     // 用户积分
                'invite_credit' => $users->invite_credit,                       // 推广积分
                'regtime' => $users->regtime,                                   // 注册时间
                'gender' => $users->gender,                                     // 性别
                'is_vip' => Customer::is_vip($users->id),                      // 是否为vip用户
            ];

            // 查询VIP客户是否存在，并获取数据
            $customer = Customer::get(['userid' => $users->id]);
            if ($customer) {
                return ApiResponse::success($result);
            } else {
                $data = [
                    'userid' => $users->id,
                    'agencyid' => '',
                    'salesmanid' => '',
                    'remark' => '业务员邀请注册',
                ];
                Customer::create($data);
                return ApiResponse::success($result);
            }
        } else {
            $data_users = [
                'mobile' => $form['mobile'],
                'regtime' => time(),
                'gender' => 0,
                'register_from' => Users::REGISTER_FROM_SALES_VIP,
            ];
            $newUser = Users::create($data_users);

            // 注册送积分
            Users::creditTask($newUser->id, UserCreditRecord::CHANGE_TYPE_REGISTER);
            // 注册送课程
            BuyBill::addBillGift($newUser->id);

            // 生成 user token
            $createUserToken = userToken($newUser->id, time());
            // 保存 user token
            saveUserToken($newUser->id, $createUserToken);

            $user = Users::get($newUser->id);

            $data_salesman = [
                'userid' => $user->id,
                'agencyid' => $salesman->agencyid,
                'salesmanid' => $salesman->id,
                'remark' => '业务员邀请注册',
            ];
            Customer::create($data_salesman);
            $result = [
                'uid' => $user->id,                                            // 用户id
                'token' => $createUserToken,                                    // 用户密钥 user token
                'mobile' => $user->mobile,                                     // 手机号
                'nickname' => ($user->nickname?:mobile_hidden(substr($user->mobile, 0, 11)))?:$user->id,  // 昵称
                'avatar' => $user->avatar ?: Users::defaultAvatar(),             // 用户头像
                'credit' => $user->credit,                                     // 用户积分
                'invite_credit' => $user->invite_credit,                       // 推广积分
                'regtime' => $user->regtime,                                   // 注册时间
                'gender' => $user->gender,                                     // 性别
                'is_vip' => Customer::is_vip($users->id),                      // 是否为vip用户
            ];
            return ApiResponse::success($result);
        }
    }

    /**
     * v1.4.1
     * 我(推广员)的推广信息
     *
     * @return ApiResponse
     *
     * @author 王雪娇
     * @date 2018-04-12
     */
    public function myPromote()
    {
        $form = $this->getAndCheckForm([
            ['platform', 'integer'],
        ]);
        $uid = checkUserToken(true);
        if (!$uid) return ApiResponse::error(ApiResponse::ERR_INVALID_REQUEST, '无效请求');
        $info = Users::infoNew($uid);
        if (!$info) return ApiResponse::error(ApiResponse::ERR_INVALID_APP, '	app token无效');
        $result['uid'] = $info['uid'];
        $result['nickname'] = $info['nickname'];
        $result['avatar'] = $info['avatar'];
        $result['extension_code'] = $info['extension_code'];
        $result['invite_url'] = $info['invite_url']??'';
        $result['invited_num'] = Users::invitedUserCount(['promoter_id' => $uid]);
        $result['total_draw_percentage_price'] = sprintf("%.2f", DrawPercentageRecord::priceSum($uid));
        if(isset($form ['platform']) && $form ['platform']==1){
            $month=date('Y-m');
            $result['current_month_invited_num']=Users::invitedUserCount(
                [
                    'promoter_id' => $uid,
                    'regtime'=>['between', [strtotime($month), strtotime($month . ' +1 month')]]
                ]
            );//本月受邀人数
            $result['current_month_order_price']=DrawPercentageRecord::getTotalPrice(
                [
                    'd.promoter_id' => $uid,
                    'b.bill_paytime'=>['between', [strtotime($month), strtotime($month . ' +1 month')]]
                ])['price'];//本月订单总额
            $result['total_order_price']=DrawPercentageRecord::getTotalPrice(['d.promoter_id' => $uid])['price'];//订单总额

        }
        return ApiResponse::success($result);
    }

    /**
     *  v1.4.1
     * 我的推广客户列表
     *
     * @return ApiResponse
     * @throws \think\exception\DbException
     *
     * @author 王雪娇
     * @date 2018-04-12
     */
    public function myInvitedUsersList()
    {
        $form = $this->getAndCheckForm([
            ['limit', 'integer',],
            ['page', 'integer',],
            ['month', 'date',],
        ]);
        $page = $form['page'] ?? 1;
        $limit = $form['limit'] ?? 10;
        $condition=[];
        if (isset($form['month']) && $form['month']) {
            $condition['regtime'] = ['between', [strtotime($form['month']), strtotime($form['month'] . ' +1 month')]];
        }
        return ApiResponse::success($this->getInvitedUsersList($condition,$page,$limit));
    }

    /**
     *  v1.4.1
     * 我的收益
     *
     * @return ApiResponse
     * @throws \think\exception\DbException
     *
     * @author 王雪娇
     * @date 2018-04-12
     */
    public function myDrawPercentage()
    {
        $form = $this->getAndCheckForm([
            ['limit', 'integer',],
            ['page', 'integer',],
            ['month', 'date',],
        ]);
        $page = $form['page'] ?? 1;
        $limit = $form['limit'] ?? 10;
        $condition=[];
        if (isset($form['month']) && $form['month']) {
            $condition['b.bill_paytime'] = ['between', [strtotime($form['month']), strtotime($form['month'] . ' +1 month')]];
        }
        return ApiResponse::success($this->getDrawPercentageData($condition,$page,$limit));
    }

    public function getDrawPercentageData(array $condition=[], $page, $limit){
        $uid = checkUserToken(true);
        $condition['d.promoter_id'] = $uid;
        $list = DrawPercentageRecord::getRecordList($condition, $page, $limit, $order = 'bill_paytime desc');
        $yesterday = DrawPercentageRecord::getTotalPrice(['d.promoter_id' => $uid, "b.bill_paytime" => ['between', [strtotime(date("Y-m-d", strtotime("-1 day"))), strtotime(date("Y-m-d"))]]]);
        $month = DrawPercentageRecord::getTotalPrice($condition);
        $total = DrawPercentageRecord::getTotalPrice(['d.promoter_id' => $uid]);
        $result = [
            'list' => $list,
            'total_page'=>$limit>0 ? ceil(DrawPercentageRecord::getRecordListCount($condition)/$limit) : 0,
            'yesterday_price_total' => $yesterday['price'],//昨天订单总额
            'yesterday_percentage_total' => $yesterday['percentage'],//昨天总收益
            'month_price_total' => $month['price'],//这个月订单总额
            'month_percentage_total' => $month['percentage'],//这个月总收益
            'price_total' => $total['price'],//订单总额
            'percentage_total' => $total['percentage'],//总收益
        ];
        return $result;
    }

    /**
     *  v1.4.1
     * 我的收益web
     *
     * @return ApiResponse
     * @throws \think\exception\DbException
     *
     * @author 王雪娇
     * @date 2018-04-26
     */
    public function myDrawPercentageWeb(){
        $form = $this->getAndCheckForm([
            ['limit', 'integer',],
            ['page', 'integer',],
            ['month', 'integer',],
            ['year', 'integer',],
        ]);
        $page = $form['page'] ?? 1;
        $limit = $form['limit'] ?? 10;
        $form['year'] = $form['year'] ?? '';
        $form['month'] = $form['month'] ?? '';
        $condition=[];
        if($form['year'] && $form['month']){
            $condition['b.bill_paytime'] = ['between', [strtotime($form['year'].'-'.$form['month']), strtotime($form['year'].'-'.$form['month'] . ' +1 month')]];
        }elseif($form['year']){
            $condition['date_part(\'year\',to_timestamp(b.bill_paytime))']=$form['year'];
        }elseif($form['month']){
            $condition['date_part(\'month\',to_timestamp(b.bill_paytime))']=$form['month'];
        }

        return ApiResponse::success($this->getDrawPercentageData($condition,$page,$limit));
    }

    /**
     *  v1.4.1
     * 我的推广客户列表web
     *
     * @return ApiResponse
     * @throws \think\exception\DbException
     *
     * @author 王雪娇
     * @date 2018-04-26
     */
    public function myInvitedUsersListWeb()
    {
        $form = $this->getAndCheckForm([
            ['limit', 'integer',],
            ['page', 'integer',],
            ['month', 'integer|between:1,12',],
            ['year', 'integer',],
        ]);
        $page = $form['page'] ?? 1;
        $limit = $form['limit'] ?? 10;
        $form['year'] = $form['year'] ?? '';
        $form['month'] = $form['month'] ?? '';
        $condition=[];
        if($form['year'] && $form['month']){
            $condition['regtime'] = ['between', [strtotime($form['year'].'-'.$form['month']), strtotime($form['year'].'-'.$form['month'] . ' +1 month')]];
        }elseif($form['year']){
            $condition['date_part(\'year\',to_timestamp(regtime))']=$form['year'];
        }elseif($form['month']){
            $condition['date_part(\'month\',to_timestamp(regtime))']=$form['month'];
        }

        return ApiResponse::success($this->getInvitedUsersList($condition,$page,$limit));


    }

    public function getInvitedUsersList(array $condition=[],$page,$limit){
        $uid = checkUserToken(true);
        $condition['promoter_id'] = $uid;
        $list = Users::invitedUserList($condition, $page, $limit, $order = 'regtime desc', $filed = 'regtime,mobile');
        if ($list) {
            foreach ($list as &$item) {
                $item->mobile = mobile_hidden($item->mobile);
                $item->regdate = date('Y-m-d', $item->regtime);
            }
        }
        $result = [
            'list' => $list,
            'yesterday_total' => Users::invitedUserCount(['promoter_id' => $uid, "regtime" => ['between', [strtotime(date("Y-m-d", strtotime("-1 day"))), strtotime(date("Y-m-d"))]]]),//昨天邀请用户总数
            'month_total' => Users::invitedUserCount($condition),//筛选月份邀请用户总数
            'total' => Users::invitedUserCount(['promoter_id' => $uid]),//一共邀请用户总数
        ];
        $result['total_page']=$limit>0 ? ceil($result['total']/$limit) : 0;
        return $result;
    }
}
